package models.security.utils;

import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import framework.utils.LogUtil;
import framework.utils.StringUtil;
import models.security.Permission;
import models.security.Resource;
import play.Play;
import play.test.Fixtures;

public class ResourceUtil {

private final static Logger logger = LogUtil.getInstance(ResourceUtil.class);
    
    /**
     * 重新加载系统的资源信息
     */
    public static void initResource(){
        if(SecurityConstant.RESOURCE_MODIFY){
            logger.info("[Platform]: System Reload Menu.");
            Resource.deleteAll(); // 重新初始化菜单资源信息
            File resourceDir = Play.getFile(SecurityConstant.RESOURCES_MENUS_DIR);
            if(resourceDir.exists() && resourceDir.isDirectory()){
                File[] menus = resourceDir.listFiles();
                String fileName = null;
                for(File f : menus){
                    fileName = f.getName();
                    if(fileName.endsWith("menu.yml")){
                        loadMenuResource(f);
                    }
                }
            }
        }
    }
    
    /**
     * 加载系统资源信息
     * @param f
     */
    private static void loadMenuResource(File f){
        String fileName = f.getName();
        logger.info(String.format("[Platform]: System Load Menu File %s",fileName));
        List<Map<String,Object>> menus =(List<Map<String,Object>>)Fixtures.loadYamlAsList(SecurityConstant.RESOURCE_MENUS_LOAD_PREFIX+fileName);
        String name = null;
        String code = null;
        String url = null;
        String _isMenu = null;
        List<Map<String,Object>> nodes = null;
        List<Map<String,String>> actions = null;
        Resource resource = null;
        Set<String> menuCodes = Permission.allMenusCode();
        Set<String> actionCodes = Permission.allActionsCode();
        Set<String> menuAddCodes = new HashSet<String>();
        Set<String> actionAddCodes = new HashSet<String>();
        for(Map<String,Object> menu : menus){
            name =StringUtil.trim(menu.get("name"));
            code = StringUtil.trim(menu.get("code"));
            _isMenu = StringUtil.trimToNull(menu.get("menu"));
            _isMenu = StringUtil.trim(_isMenu,"true");
            resource = new Resource(name,code,null,SecurityConstant.RESOURCE_MENU_TYPE_NAME,_isMenu);
            resource.save();
            if(!menuCodes.contains(code)){
                menuCodes.add(code);
                menuAddCodes.add(code);
            }
            if(menu.containsKey("nodes")){
                nodes = (List<Map<String, Object>>) menu.get("nodes");
                for(Map<String,Object> node : nodes){
                    name = StringUtil.trim(node.get("name"));
                    code = StringUtil.trim(node.get("code"));
                    url = StringUtil.trim(node.get("url"));
                    _isMenu = StringUtil.trimToNull(node.get("menu"));
                    _isMenu = StringUtil.trim(_isMenu,"true");
                    resource = new Resource(name,code,url,SecurityConstant.RESOURCE_MENU_TYPE_NAME,_isMenu);
                    resource.save();
                    if(!menuCodes.contains(code)){
                        menuCodes.add(code);
                        menuAddCodes.add(code);
                    }
                    if(node.containsKey("actions")){
                        actions = (List<Map<String, String>>) node.get("actions");
                        for(Map<String,String> action : actions){
                            name = action.get("name");
                            code = action.get("code");
                            resource  = new Resource(name,code,null,SecurityConstant.RESOURCE_ACTION_TYPE_NAME);
                            resource.save();
                            if(!actionCodes.contains(code)){
                                actionCodes.add(code);
                                actionAddCodes.add(code);
                            }
                        }
                    }
                }
            }
        }
        
        if(null!=menuAddCodes && !menuAddCodes.isEmpty()){
            Permission.batchAdd(menuAddCodes, SecurityConstant.RESOURCE_MENU_TYPE_NAME);
        }
        if(null!=actionAddCodes && !actionAddCodes.isEmpty()){
            Permission.batchAdd(actionAddCodes, SecurityConstant.RESOURCE_ACTION_TYPE_NAME);
        }
    }
}
    
